/*
 * @Description: 电影剧集服务层
 * @Author: fhw
 * @Date: 2024-06-15
 */

import { Injectable, UseFilters } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, In } from 'typeorm';
import { MoviesEpisodeEntity } from './entities/movies-episode.entity';
import { MovieEntity } from '../movies/entities/movie.entity';
import { HttpExceptionFilter } from 'src/common/http-exception.filter';
import { getPagination, throwHttp } from 'src/utlis';
import { isTrue } from 'src/utlis/tools';
import { IdDto } from 'src/common/dto/dto';
import { CreateMoviesEpisodeDto, GetMoviesEpisodeDto, UpdateMoviesEpisodeDto } from './dto/movies-episode.dto';

@Injectable()
export class MoviesEpisodeService {
  constructor(
    @InjectRepository(MoviesEpisodeEntity)
    private readonly episodeRepository: Repository<MoviesEpisodeEntity>,

    @InjectRepository(MovieEntity)
    private readonly movieRepository: Repository<MovieEntity>,
  ) { }

  /** 创建剧集 */
  @UseFilters(new HttpExceptionFilter())
  async createEpisode(body: CreateMoviesEpisodeDto) {
    try {
      const movie = await this.movieRepository.findOne({ where: { id: body.movieId } });
      if (!isTrue(movie)) {
        throwHttp('关联的电影不存在');
        return;
      }

      const episode = new MoviesEpisodeEntity();
      episode.name = body.name;
      episode.episodeNumber = body.episodeNumber;
      episode.mp4 = body.mp4;
      episode.cover = body.cover;
      episode.amount = body.amount;
      episode.free = body.free;
      episode.status = body.status;
      episode.likeCount = body.likeCount;
      episode.playCount = body.playCount;
      episode.collectCount = body.collectCount;
      episode.movies = movie;

      const result = await this.episodeRepository.save(episode);
      if (isTrue(result)) {
        return result;
      }
      throwHttp('剧集创建失败');
    } catch (error) {
      throwHttp(error.message);
    }
  }

  /** 更新剧集 */
  @UseFilters(new HttpExceptionFilter())
  async updateEpisode(body: UpdateMoviesEpisodeDto) {
    try {
      const episode = await this.episodeRepository.findOne({ where: { id: body.id } });
      if (!isTrue(episode)) {
        throwHttp('剧集不存在');
        return;
      }

      const movie = await this.movieRepository.findOne({ where: { id: body.movieId } });
      if (!isTrue(movie)) {
        throwHttp('关联的电影不存在');
        return;
      }

      const { affected } = await this.episodeRepository
        .createQueryBuilder()
        .update(MoviesEpisodeEntity)
        .set({
          name: body.name,
          episodeNumber: body.episodeNumber,
          mp4: body.mp4,
          cover: body.cover,
          amount: body.amount,
          free: body.free,
          status: body.status,
          likeCount: body.likeCount,
          playCount: body.playCount,
          collectCount: body.collectCount,
          movies: movie,
        })
        .where('id = :id', { id: body.id })
        .execute();

      if (affected) {
        return '剧集更新成功';
      }
      throwHttp('剧集更新失败');
    } catch (error) {
      throwHttp(error.message);
    }
  }

  /** 获取剧集列表 */
  @UseFilters(new HttpExceptionFilter())
  async getEpisodePage(params: GetMoviesEpisodeDto) {
    try {
      const { name, movieId } = params;
      const where: any = { name, movies: { id: movieId } };

      // 过滤 undefined 属性
      Object.keys(where).forEach(key => where[key] === undefined && delete where[key]);

      // 分页
      const { pageSize, pageNum } = getPagination({
        pageSize: params.pageSize,
        pageNum: params.pageNum,
      });

      const [data, total] = await this.episodeRepository.findAndCount({
        where,
        cache: true,
        skip: pageNum * pageSize,
        take: pageSize,
        order: { episodeNumber: 'ASC', createDate: 'DESC', },
        relations: ['movies'],
      });

      return {
        data,
        total,
        pageSize,
        pageNum: pageNum + 1,
      };
    } catch (error) {
      throwHttp(error.message);
    }
  }

  /** 获取剧集详情 */
  @UseFilters(new HttpExceptionFilter())
  async getEpisodeInfo(id: number) {
    try {
      return await this.episodeRepository.findOne({
        where: { id },
        cache: true,
        relations: ['movies'],
      });
    } catch (error) {
      throwHttp(error.message);
    }
  }

  /** 删除剧集 */
  @UseFilters(new HttpExceptionFilter())
  async deleteEpisode({ id }: IdDto) {
    try {
      const episode = await this.getEpisodeInfo(id);
      if (!isTrue(episode)) {
        throwHttp('剧集不存在');
        return;
      }

      await this.episodeRepository.softDelete(id);
      return '剧集删除成功';
    } catch (error) {
      throwHttp(error.message);
    }
  }
}
